import sys
import json
import os

from datetime import datetime
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                              QHBoxLayout, QGroupBox, QTableWidget, QInputDialog,
                              QComboBox, QLineEdit, QPushButton,
                              QHeaderView, QMessageBox, QFileDialog)
from components.colored_combobox import ColoredComboBox
from components.extended_combobox import ExtendedComboBox

class StepFilterWidget(QWidget):
    """工步筛选组件，包含筛选类型和工步号输入"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.init_ui()
        
    def init_ui(self):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(2, 2, 2, 2)
        
        # 筛选类型选择
        self.type_combo = QComboBox()
        self.type_combo.addItems(["全部", "包含"])
        self.type_combo.currentIndexChanged.connect(self.on_type_changed)
        layout.addWidget(self.type_combo)
        
        # 工步号输入
        self.values_edit = QLineEdit()
        self.values_edit.setPlaceholderText("例如: 1,2,3")
        self.values_edit.setEnabled(False)  # 初始禁用
        layout.addWidget(self.values_edit)
        
    def on_type_changed(self, index):
        """根据筛选类型启用/禁用工步号输入"""
        self.values_edit.setEnabled(index != 0)  # 0 是"全部"选项

    def set_work_step(self, work_step: list):
        if not work_step:
            self.type_combo.setCurrentText("全部")
        else:
            self.type_combo.setCurrentText("包含")
            self.values_edit.setText(",".join([str(item) for item in work_step]))

    def get_value(self):
        """获取工步筛选配置"""
        filter_type = self.type_combo.currentText()
        if filter_type == "全部":
            return []
        
        # 解析输入的工步号
        try:
            values = [int(v.strip()) for v in self.values_edit.text().split(",") if v.strip()]
            return values
        except ValueError:
            return []

class CalculationWidget(QWidget):
    """计算方式选择组件，支持多选"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.init_ui()
        
    def init_ui(self):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(2, 2, 2, 2)
        
        self.calc_combo = QComboBox()
        # 添加计算方式选项
        self.calc_types = [
            "起始值", "截止值", "最大值", "最小值", 
            "差值 (最后一行 - 第一行前一行)", 
            "行末累加", "差值累加"
        ]
        self.calc_combo.addItems(self.calc_types)

        # 默认选中第一个
        self.calc_combo.setCurrentIndex(0)
        
        layout.addWidget(self.calc_combo)

    def set_method(self, method: str):
        self.calc_combo.setCurrentText(method)

    def get_value(self):
        """获取选中的计算方式"""
        return self.calc_combo.currentText()

class IndicatorTable(QTableWidget):
    """指标配置表格"""
    def __init__(self, parent=None):
        super().__init__(0, 6, parent)  # 初始0行，7列
        self.init_ui()
        self.base_columns = ["充电容量", "充电能量", "放电容量", "放电能量"]
        
    def init_ui(self):
        # 设置表头
        headers = ["基础数据列", "小循环序号", "状态筛选", "工步筛选", "计算方式", "操作"]
        self.setHorizontalHeaderLabels(headers)
        
        # 设置列宽
        header = self.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.Stretch)
        header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(5, QHeaderView.ResizeToContents)

    def init_from_config(self, config_list):
        """根据配置文件初始化表格"""
        self.setRowCount(0)
        for config in config_list:
            column = config['column']
            small_cycle = config['small_cycle']
            status = config['status']
            work_step = config['work_step']
            method = config['method']

            row = self.rowCount()
            self.insertRow(row)
            # 基础数据列
            base_col_combo = ExtendedComboBox()
            base_col_combo.setCurrentText(column)
    
            self.setCellWidget(row, 0, base_col_combo)

            # 小循环序号
            cycle_combo = QComboBox()
            cycle_combo.addItems(["全部", *[str(i) for i in range(1, 31)]])
            if small_cycle:
                cycle_combo.setCurrentText(small_cycle[0])
            else:
                cycle_combo.setCurrentText("全部")
            self.setCellWidget(row, 1, cycle_combo)

            # 状态筛选
            status_combo = ColoredComboBox()
            status_combo.addItems(["全部", "充电", "放电", "静置"])
            status_combo.setCurrentText(status)
            self.setCellWidget(row, 2, status_combo)

            # 工步筛选
            step_filter = StepFilterWidget()  # 假设 StepFilterWidget 可无参初始化，或根据 work_step 传参
            # 若 StepFilterWidget 需要设置 work_step 数据，这里补充逻辑，比如：
            step_filter.set_work_step(work_step)
            self.setCellWidget(row, 3, step_filter)
            
            # 计算方式
            calc_widget = CalculationWidget()  # 假设 CalculationWidget 可无参初始化，或根据 method 传参
            # 若 CalculationWidget 需要设置 method 数据，这里补充逻辑，比如：
            calc_widget.set_method(method)
            self.setCellWidget(row, 4, calc_widget)
            
            # 操作按钮
            btn_widget = QWidget()
            btn_layout = QHBoxLayout(btn_widget)
            btn_layout.setContentsMargins(2, 2, 2, 2)
            
            add_btn = QPushButton("+")
            add_btn.setStyleSheet("background-color: #00C851; color: white;")
            add_btn.clicked.connect(self.add_row)
            
            delete_btn = QPushButton("-")
            delete_btn.setStyleSheet("background-color: #ff4444; color: white;font-weight: bold;")
            delete_btn.clicked.connect(self.delete_row)  # 注意闭包传参
            
            btn_layout.addWidget(add_btn)
            btn_layout.addWidget(delete_btn)
            self.setCellWidget(row, 5, btn_widget)
            
            self.resizeRowToContents(row)

    def add_row(self):
        """添加一行新的指标配置"""
        button = self.sender()
        if not button:
            return
        # 找到按钮所在的部件
        widget = button.parent()
        if not widget:
            return
        # 获取部件所在的单元格位置
        row = self.indexAt(widget.pos()).row()
        self.insertRow(row + 1)
        row = row + 1
        # 基础数据列
        combobox = self.cellWidget(0, 0)
        model = combobox.model()
        items2 = []
        for i in range(model.rowCount()):
            # 获取第i行第0列的文本数据
            items2.append(model.data(model.index(i, 0)))
        base_col_combo = ExtendedComboBox()
        base_col_combo.addItems([*self.base_columns, *items2])
        self.setCellWidget(row, 0, base_col_combo)
        
        # 小循环序号
        cycle_combo = QComboBox()
        cycle_combo.addItems(["全部", *[str(i) for i in range(1, 21)]])
        self.setCellWidget(row, 1, cycle_combo)

        # 状态筛选
        status_combo = ColoredComboBox(["全部", "充电", "放电", "静置"])
        self.setCellWidget(row, 2, status_combo)
        
        # 工步筛选
        step_filter = StepFilterWidget()
        self.setCellWidget(row, 3, step_filter)
        
        # 计算方式
        calc_widget = CalculationWidget()
        self.setCellWidget(row, 4, calc_widget)
        
        # 操作按钮
        btn_widget = QWidget()
        btn_layout = QHBoxLayout(btn_widget)
        btn_layout.setContentsMargins(2, 2, 2, 2)
        
        add_btn = QPushButton("+")
        add_btn.setStyleSheet("background-color: #00C851; color: white;")
        add_btn.clicked.connect(self.add_row)
        
        delete_btn = QPushButton("-")
        delete_btn.setStyleSheet("background-color: #ff4444; color: white;font-weight: bold;")
        delete_btn.clicked.connect(self.delete_row)
        
        btn_layout.addWidget(add_btn)
        btn_layout.addWidget(delete_btn)
        self.setCellWidget(row, 5, btn_widget)
        
        # 自动调整行高
        self.resizeRowToContents(row)
        
    def delete_row(self):
        """删除指定行"""
        button = self.sender()
        if not button:
            return
        # 找到按钮所在的部件
        widget = button.parent()
        if not widget:
            return
        # 获取部件所在的单元格位置
        row = self.indexAt(widget.pos()).row()

        if self.rowCount() <= 1:
            QMessageBox.information(self, "提示", "至少保留一行")
            return
            
        self.removeRow(row)
    
    def get_all_configs(self):
        """获取所有指标的配置信息"""
        configs = []
        
        for row in range(self.rowCount()):
            # 基础数据列
            base_col = self.cellWidget(row, 0).currentText()
            
            # 小循环序号
            cycle_num = self.cellWidget(row, 1).currentText()
            cycle_num = None if cycle_num == "全部" else int(cycle_num)
            
            # 状态筛选
            status = self.cellWidget(row, 2).currentText()
            
            # 工步筛选
            work_step = self.cellWidget(row, 3).get_value()
            
            # 计算方式
            method = self.cellWidget(row, 4).get_value()

            configs.append({
                "column": base_col,
                "small_cycle": cycle_num,
                "status": status,
                "work_step": work_step,
                "method": method
            })
            
        return configs

    @staticmethod
    def combine_strings(str_list):
        """
        处理字符串列表，返回去重后的原列表与所有A-B形式组合的合并列表（A≠B）
        
        参数:
            str_list: 输入的字符串列表
            
        返回:
            合并后的字符串列表（已去重）
        """
        # 对原列表去重，保持原始顺序
        unique_strs = list(dict.fromkeys(str_list))
        
        # 生成所有A-B形式的组合（A≠B）
        combinations = []
        for a in unique_strs:
            for b in unique_strs:
                if a != b:  # 排除A-A、B-B这类情况
                    combinations.append(f"{a}-{b}")
        
        # 对组合结果去重（避免可能的重复，如不同对生成相同组合）
        unique_combinations = list(dict.fromkeys(combinations))
        
        # 合并原列表和组合结果，并再次去重
        final_result = list(dict.fromkeys(unique_strs + unique_combinations))
        
        return final_result

    def update_columns(self, columns: list):
        items = self.combine_strings(columns)
        items = dict.fromkeys(['充电容量', '充电能量', '放电容量', '放电能量', *items])
        for row in range(self.rowCount()):
            combobox = self.cellWidget(row, 0)
            currentex = combobox.currentText()
            combobox.clear()
            combobox.addItems(items)
            combobox.setCurrentText(currentex)

class DataConfigurator(QMainWindow):
    CONFIG_DIR = "static/indicator"

    def __init__(self):
        super().__init__()
        self.configs = []
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle("数据指标配置表格")
        
        # 中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)
        
        # 指标表格
        table_group = QGroupBox("指标配置列表")
        table_layout = QVBoxLayout()
        
        self.indicator_table = IndicatorTable()
        table_layout.addWidget(self.indicator_table)
        
        table_group.setLayout(table_layout)
        main_layout.addWidget(table_group)
        
        # 底部按钮
        btn_layout = QHBoxLayout()
        self.load_btn = QPushButton("加载指标")
        self.reset_btn = QPushButton("清空指标")
        self.export_btn = QPushButton("导出指标")
        self.save_btn = QPushButton("保存指标")

        btn_layout.addWidget(self.load_btn)
        btn_layout.addWidget(self.reset_btn)
        btn_layout.addWidget(self.export_btn)
        btn_layout.addWidget(self.save_btn)
        main_layout.addLayout(btn_layout)
        
        # 连接信号
        self.load_btn.clicked.connect(self.on_apply_config)
        self.reset_btn.clicked.connect(self.on_reset_config)
        self.save_btn.clicked.connect(self.on_save_config)
        self.export_btn.clicked.connect(self.export_config)

    def export_config(self):
        # 实现导出配置到文件的功能
        # 获取当前表格中的数据
        current_config = self.get_all_configs()
        
        # 生成文件名
        current_date = datetime.now().strftime("%Y%m%d")
        default_file_name = f"配置{current_date}.json"
        
        file_path, _ = QFileDialog.getSaveFileName(
            self, "导出配置文件", default_file_name, "JSON文件 (*.json)"
        )
        if file_path:
            try:
                with open(file_path, 'w', encoding='utf-8') as f:
                    json.dump(current_config, f, ensure_ascii=False, indent=4)
                
                self.statusBar().showMessage(f"配置已导出到: {os.path.basename(file_path)}")
                QMessageBox.information(self, "成功", "配置导出成功！")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"导出配置失败: {str(e)}")

    def on_save_config(self):
        configs = self.get_all_configs()
                # 提示用户输入配置名称
        name, ok = QInputDialog.getText(
            self, "保存输出指标", "输入指标名称:"
        )
        if not ok or not name:
            return
        file_name = f"{name}.json"
        file_path = os.path.join(self.CONFIG_DIR, file_name)
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(configs, f, ensure_ascii=False, indent=4)
            QMessageBox.information(self, "信息", f"已保存BMS配置:\n {os.path.dirname(__file__)}\\static\\indicator\\{name}.json")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存配置失败: {str(e)}")

    def init_from_config(self, configs):
        self.configs = configs
        return self.indicator_table.init_from_config(configs)

    def get_all_configs(self):
        return self.indicator_table.get_all_configs()

    def on_apply_config(self):
        """加载指标"""
        file_path, _ = QFileDialog.getOpenFileName(
                    self, "选择配置文件", self.CONFIG_DIR, "JSON文件 (*.json)"
                )
        if file_path:
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    configs = json.load(f)
                    self.init_from_config(configs)
                QMessageBox.information(self, "成功", "配置加载成功！")

            except Exception as e:
                QMessageBox.critical(self, "错误", f"加载配置失败: {str(e)}")

    def on_reset_config(self):
        """重置配置"""
        # 清空表格并添加一行默认配置
        self.indicator_table.setRowCount(1)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = DataConfigurator()
    window.show()
    sys.exit(app.exec())
